"""
Main application window.
"""

import os
from typing import Optional
from pathlib import Path

from PyQt6.QtWidgets import (
    QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QSplitter,
    QMenuBar, QToolBar, QStatusBar, QMessageBox, QFileDialog,
    QLabel, QPushButton, QProgressBar, QFrame
)
from PyQt6.QtCore import Qt, QTimer, pyqtSlot, QThread
from PyQt6.QtGui import QAction, QIcon, QDragEnterEvent, QDropEvent

from ..core.pdf_processor import PDFProcessor, PDFLoadWorker
from ..core.pdf_splitter import PDFSplitter, SplitMode
from .preview_widget import PreviewWidget
from .dialogs.split_dialog_simple import SimpleSplitDialog as SplitDialog
from ..utils.settings_manager import get_settings_manager
from ..i18n import tr, set_global_translator


class MainWindow(QMainWindow):
    """Main application window."""

    def __init__(self, translator=None):
        super().__init__()
        self.translator = translator
        # Set global translator
        if translator:
            set_global_translator(translator)

        self.pdf_processor = PDFProcessor()
        self.pdf_splitter = PDFSplitter(self.pdf_processor)
        self.current_file_path: Optional[str] = None
        self.load_worker: Optional[PDFLoadWorker] = None
        self.load_thread: Optional[QThread] = None
        self.settings_manager = get_settings_manager()

        self.init_ui()
        self.setup_connections()
        self.retranslate_ui()

        # Update language menu check state based on current language
        if self.translator:
            current_lang = self.translator.get_current_language()
            if current_lang in self.language_actions:
                self.language_actions[current_lang].setChecked(True)

    def init_ui(self):
        """Initialize the user interface."""
        # Window settings
        self.setWindowTitle(tr("PDF Splitter"))
        self.setMinimumSize(1200, 800)
        self.resize(1400, 900)

        # Enable drag and drop
        self.setAcceptDrops(True)

        # Create central widget
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # Create main layout
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(5, 5, 5, 5)

        # Create toolbar
        self.create_toolbar()
        self.create_menubar()

        # Create splitter for main content
        self.main_splitter = QSplitter(Qt.Orientation.Horizontal)

        # Create preview widget
        self.preview_widget = PreviewWidget()
        self.preview_widget.setMinimumWidth(300)

        # Create info panel
        self.info_panel = self.create_info_panel()
        self.info_panel.setMaximumWidth(400)

        # Add to splitter
        self.main_splitter.addWidget(self.preview_widget)
        self.main_splitter.addWidget(self.info_panel)
        self.main_splitter.setStretchFactor(0, 3)
        self.main_splitter.setStretchFactor(1, 1)

        # Add to main layout
        main_layout.addWidget(self.main_splitter)

        # Create status bar
        self.create_statusbar()

        # Initially disable split action
        self.split_action.setEnabled(False)

    def create_toolbar(self):
        """Create the toolbar."""
        self.toolbar = QToolBar(tr("Main Toolbar"))
        self.addToolBar(self.toolbar)

        # Open action
        self.open_action = QAction(QIcon.fromTheme("document-open"), tr("Open PDF"), self)
        self.open_action.setShortcut("Ctrl+O")
        self.open_action.triggered.connect(self.open_file)
        self.toolbar.addAction(self.open_action)

        self.toolbar.addSeparator()

        # Split action
        self.split_action = QAction(QIcon.fromTheme("edit-cut"), tr("Split PDF"), self)
        self.split_action.setShortcut("Ctrl+S")
        self.split_action.triggered.connect(self.show_split_dialog)
        self.toolbar.addAction(self.split_action)

        self.toolbar.addSeparator()

        # Exit action
        self.exit_action = QAction(QIcon.fromTheme("application-exit"), tr("Exit"), self)
        self.exit_action.setShortcut("Ctrl+Q")
        self.exit_action.triggered.connect(self.close)
        self.toolbar.addAction(self.exit_action)

    def create_menubar(self):
        """Create the menu bar."""
        menubar = self.menuBar()

        # File menu
        self.file_menu = menubar.addMenu(tr("File"))
        self.file_menu.addAction(self.open_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.split_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(tr("Exit"), self.close).setShortcut("Ctrl+Q")

        # Edit menu
        self.edit_menu = menubar.addMenu(tr("Edit"))
        self.edit_menu.addAction(tr("Select All"), self.select_all_pages).setShortcut("Ctrl+A")
        self.edit_menu.addAction(tr("Deselect All"), self.deselect_all_pages).setShortcut("Ctrl+D")

        # View menu
        self.view_menu = menubar.addMenu(tr("View"))
        self.view_menu.addAction(tr("Zoom In"), self.zoom_in).setShortcut("Ctrl++")
        self.view_menu.addAction(tr("Zoom Out"), self.zoom_out).setShortcut("Ctrl+-")
        self.view_menu.addAction(tr("Reset Zoom"), self.reset_zoom).setShortcut("Ctrl+0")

        # Language menu
        self.language_menu = menubar.addMenu(tr("Language"))
        self.language_actions = {}

        # Add language options
        from ..i18n import SUPPORTED_LANGUAGES, get_language_native_name
        for lang_code, (lang_name, native_name) in SUPPORTED_LANGUAGES.items():
            action = QAction(f"{native_name} ({lang_code})", self)
            action.setCheckable(True)
            action.setData(lang_code)
            action.triggered.connect(lambda checked, code=lang_code: self.change_language(code))
            self.language_menu.addAction(action)
            self.language_actions[lang_code] = action

        # Help menu
        self.help_menu = menubar.addMenu(tr("Help"))
        self.help_menu.addAction(tr("About"), self.show_about)

    def create_info_panel(self) -> QWidget:
        """Create the information panel."""
        panel = QFrame()
        panel.setFrameStyle(QFrame.Shape.StyledPanel)
        panel.setLineWidth(1)

        layout = QVBoxLayout(panel)

        # Title
        self.doc_info_title = QLabel(tr("Document Information"))
        self.doc_info_title.setStyleSheet("font-size: 14px; font-weight: bold; margin: 5px;")
        layout.addWidget(self.doc_info_title)

        # Document info
        self.doc_info_label = QLabel(tr("No document loaded"))
        self.doc_info_label.setWordWrap(True)
        self.doc_info_label.setStyleSheet("margin: 10px; color: #666;")
        layout.addWidget(self.doc_info_label)

        # Separator
        line = QFrame()
        line.setFrameShape(QFrame.Shape.HLine)
        layout.addWidget(line)

        # Split settings
        self.split_title = QLabel(tr("Quick Split"))
        self.split_title.setStyleSheet("font-size: 14px; font-weight: bold; margin: 5px;")
        layout.addWidget(self.split_title)

        # Quick split buttons
        self.quick_split_single_btn = QPushButton(tr("Split Each Page"))
        self.quick_split_single_btn.clicked.connect(
            lambda: self.quick_split(1)
        )
        layout.addWidget(self.quick_split_single_btn)

        self.quick_split_dual_btn = QPushButton(tr("Split into 2-Page Sections"))
        self.quick_split_dual_btn.clicked.connect(
            lambda: self.quick_split(2)
        )
        layout.addWidget(self.quick_split_dual_btn)

        # Custom split button
        self.custom_split_btn = QPushButton(tr("Custom Split..."))
        self.custom_split_btn.clicked.connect(self.show_split_dialog)
        self.custom_split_btn.setStyleSheet("margin-top: 10px;")
        layout.addWidget(self.custom_split_btn)

        # Add stretch to push everything up
        layout.addStretch()

        return panel

    def create_statusbar(self):
        """Create the status bar."""
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)

        # Status label
        self.status_label = QLabel(tr("Ready"))
        self.status_bar.addWidget(self.status_label)

        # Progress bar (initially hidden)
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        self.status_bar.addPermanentWidget(self.progress_bar)

    def setup_connections(self):
        """Setup signal connections."""
        # Preview widget connections
        self.preview_widget.page_selected.connect(self.on_page_selected)
        self.preview_widget.selection_changed.connect(self.on_selection_changed)

    def dragEnterEvent(self, event: QDragEnterEvent):
        """Handle drag enter events."""
        if event.mimeData().hasUrls():
            urls = event.mimeData().urls()
            if len(urls) == 1 and urls[0].isLocalFile():
                file_path = urls[0].toLocalFile()
                if file_path.lower().endswith('.pdf'):
                    event.acceptProposedAction()

    def dropEvent(self, event: QDropEvent):
        """Handle drop events."""
        if event.mimeData().hasUrls():
            urls = event.mimeData().urls()
            if len(urls) == 1:
                file_path = urls[0].toLocalFile()
                if file_path.lower().endswith('.pdf'):
                    self.load_file(file_path)

    def open_file(self):
        """Open a PDF file."""
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            tr("Open PDF File"),
            "",
            tr("PDF Files (*.pdf);;All Files (*)")
        )
        if file_path:
            self.load_file(file_path)

    def load_file(self, file_path: str):
        """Load a PDF file."""
        if not os.path.exists(file_path):
            QMessageBox.warning(self, tr("Error"), tr("File not found: %1", file_path))
            return

        # Update status
        self.status_label.setText(tr("Loading PDF..."))
        self.progress_bar.setVisible(True)
        self.progress_bar.setRange(0, 0)  # Indeterminate progress

        # Create worker
        self.load_worker = PDFLoadWorker(file_path)
        self.load_thread = QThread()
        self.load_worker.moveToThread(self.load_thread)

        # Connect signals
        self.load_worker.finished.connect(self.on_file_loaded)
        self.load_worker.progress.connect(self.progress_bar.setValue)
        self.load_thread.finished.connect(self._on_load_thread_finished)
        self.load_thread.started.connect(self.load_worker.run)

        # Start loading
        self.load_thread.start()

    @pyqtSlot(object, str)
    def on_file_loaded(self, processor: PDFProcessor, error: str):
        """Handle file loaded signal."""
        # Hide progress bar
        self.progress_bar.setVisible(False)

        if error:
            self.status_label.setText(tr("Failed to load PDF"))
            QMessageBox.critical(self, tr("Error"), tr("Failed to load PDF: %1", error))
            return

        # Update processor
        self.pdf_processor = processor
        self.pdf_splitter = PDFSplitter(processor)
        self.current_file_path = processor.get_file_path()

        # Update UI
        self.update_document_info()
        self.preview_widget.load_document(processor)
        self.split_action.setEnabled(True)
        self.quick_split_single_btn.setEnabled(True)
        self.quick_split_dual_btn.setEnabled(True)

        # Update status
        self.status_label.setText(tr("Loaded: %1", os.path.basename(self.current_file_path)))

        # Clean up worker thread
        if self.load_thread:
            self.load_thread.quit()
            self.load_thread.wait()
            self.load_thread = None
        self.load_worker = None

    @pyqtSlot()
    def _on_load_thread_finished(self):
        """Handle load thread finished."""
        # This ensures proper cleanup even if the thread finishes unexpectedly
        if self.load_thread:
            self.load_thread.wait(100)  # Wait a bit for the thread to actually finish
            self.load_thread.deleteLater()
            self.load_thread = None

    def update_document_info(self):
        """Update document information display."""
        if not self.pdf_processor.is_loaded():
            self.doc_info_label.setText(tr("No document loaded"))
            return

        metadata = self.pdf_processor.get_metadata()
        info_text = tr(
            "<strong>File:</strong> %1<br>"
            "<strong>Pages:</strong> %2<br>"
            "<strong>Size:</strong> %3 bytes<br>"
            "<strong>Encrypted:</strong> %4",
            os.path.basename(self.current_file_path) if self.current_file_path else tr("Unknown"),
            str(metadata.page_count),
            f"{metadata.file_size:,}",
            tr("Yes") if metadata.encrypted else tr("No")
        )

        if metadata.title:
            info_text += f"<br><strong>{tr('Title')}:</strong> {metadata.title}"
        if metadata.author:
            info_text += f"<br><strong>{tr('Author')}:</strong> {metadata.author}"

        self.doc_info_label.setText(info_text)

    def quick_split(self, pages_per_file: int):
        """Perform quick split with specified pages per file."""
        if not self.pdf_processor.is_loaded():
            return

        # Get output directory
        output_dir = QFileDialog.getExistingDirectory(
            self,
            tr("Select Output Directory"),
            os.path.dirname(self.current_file_path) if self.current_file_path else ""
        )

        if not output_dir:
            return

        # Update status
        self.status_label.setText(tr("Splitting into %1-page files...", pages_per_file))
        self.progress_bar.setVisible(True)
        self.progress_bar.setRange(0, 100)

        # TODO: Implement background splitting
        # For now, show a message
        QMessageBox.information(
            self,
            tr("Quick Split"),
            tr("This would split the PDF into files with %1 pages each.\n"
                    "Output directory: %2", pages_per_file, output_dir)
        )

        self.progress_bar.setVisible(False)

    def show_split_dialog(self):
        """Show the split configuration dialog."""
        if not self.pdf_processor.is_loaded():
            return

        dialog = SplitDialog(
            self.pdf_processor,
            self.pdf_splitter,
            self.current_file_path,
            self
        )
        dialog.exec()

    def select_all_pages(self):
        """Select all pages."""
        if self.pdf_processor.is_loaded():
            self.preview_widget.select_all_pages()

    def deselect_all_pages(self):
        """Deselect all pages."""
        if self.pdf_processor.is_loaded():
            self.preview_widget.deselect_all_pages()

    def zoom_in(self):
        """Zoom in the preview."""
        self.preview_widget.zoom_in()

    def zoom_out(self):
        """Zoom out the preview."""
        self.preview_widget.zoom_out()

    def reset_zoom(self):
        """Reset zoom to default."""
        self.preview_widget.reset_zoom()

    @pyqtSlot(int)
    def on_page_selected(self, page_index: int):
        """Handle page selection."""
        self.status_label.setText(tr("Page %1 selected", page_index + 1))

    @pyqtSlot(list)
    def on_selection_changed(self, selected_pages: list):
        """Handle selection change."""
        if selected_pages:
            self.status_label.setText(tr("%1 pages selected", len(selected_pages)))
        else:
            self.status_label.setText(tr("No pages selected"))

    def retranslate_ui(self):
        """Retranslate all UI strings."""
        # Update window title
        self.setWindowTitle(tr("PDF Splitter"))

        # Update menu items
        # These will be automatically updated by Qt

        # Update info panel
        if hasattr(self, 'doc_info_label'):
            if self.pdf_processor.is_loaded():
                self.update_document_info()
            else:
                self.doc_info_label.setText(tr("No document loaded"))

        # Update status
        if hasattr(self, 'status_label'):
            self.status_label.setText(tr("Ready"))

    def change_language(self, language_code: str):
        """Change application language."""
        if not self.translator:
            return

        # Set the new language
        self.translator.set_language(language_code)

        # Update language menu check state
        for lang_code_action, action in self.language_actions.items():
            action.setChecked(lang_code_action == language_code)

        # Save language preference
        self.settings_manager.update_settings(language=language_code)
        self.settings_manager.save_settings()

        # Retranslate UI
        self.retranslate_ui()

        # Update preview widget if it supports translation
        if hasattr(self.preview_widget, 'retranslate_ui'):
            self.preview_widget.retranslate_ui()

    def show_about(self):
        """Show about dialog."""
        QMessageBox.about(
            self,
            tr("About PDF Splitter"),
            tr("<b>%1 v0.1.0</b><br><br>"
               "%2<br><br>"
               "%3",
               tr("PDF Splitter"),
               tr("A cross-platform PDF file splitter application."),
               tr("Built with PyQt6 and PyMuPDF."))
        )

    def closeEvent(self, event):
        """Handle window close event."""
        # Close any loaded document
        if self.pdf_processor:
            self.pdf_processor.close()

        # Cancel any ongoing loading
        if self.load_worker and self.load_thread:
            self.load_worker.cancel()
            self.load_thread.quit()
            self.load_thread.wait(2000)  # Wait up to 2 seconds
            if self.load_thread.isRunning():
                self.load_thread.terminate()
                self.load_thread.wait(500)  # Final wait
            self.load_thread = None
            self.load_worker = None

        event.accept()